#include <OcctWindow.h>

#include <QGuiApplication>
#include <QScreen>

IMPLEMENT_STANDARD_RTTIEXT(OcctWindow, Aspect_Window)

// =======================================================================
// function : OcctWindow
// purpose  :
// =======================================================================
OcctWindow::OcctWindow(QWidget* theWidget, const Quantity_NameOfColor theBackColor)
    : Aspect_Window(),
    myWidget(theWidget)
{
    SetBackground(theBackColor);

    GetSize(myXLeft, myXRight, myYTop, myYBottom);
}

// =======================================================================
// function : Destroy
// purpose  :
// =======================================================================
void OcctWindow::Destroy()
{
    myWidget = NULL;
}

// =======================================================================
// function : NativeParentHandle
// purpose  :
// =======================================================================
Aspect_Drawable OcctWindow::NativeParentHandle() const
{
    QWidget* aParentWidget = myWidget->parentWidget();
    if (aParentWidget != NULL)
        return (Aspect_Drawable)aParentWidget->winId();
    else
        return 0;
}

// =======================================================================
// function : NativeHandle
// purpose  :
// =======================================================================
Aspect_Drawable OcctWindow::NativeHandle() const
{
    return (Aspect_Drawable)myWidget->winId();
}

// =======================================================================
// function : IsMapped
// purpose  :
// =======================================================================
Standard_Boolean OcctWindow::IsMapped() const
{
    return !(myWidget->isMinimized() || myWidget->isHidden());
}

// =======================================================================
// function : Map
// purpose  :
// =======================================================================
void OcctWindow::Map() const
{
    myWidget->show();
    myWidget->update();
}

// =======================================================================
// function : Unmap
// purpose  :
// =======================================================================
void OcctWindow::Unmap() const
{
    myWidget->hide();
    myWidget->update();
}

// =======================================================================
// function : DoResize
// purpose  :
// =======================================================================
Aspect_TypeOfResize OcctWindow::DoResize()
{
    int                 aMask = 0;
    Aspect_TypeOfResize aMode = Aspect_TOR_UNKNOWN;

    if (!myWidget->isMinimized())
    {
        int xl = 0, xr = 0, yt = 0, yb = 0;
        GetSize(xl, xr, yt, yb);

        if (Abs(xl - myXLeft) > 2) aMask |= 1;
        if (Abs(xr - myXRight) > 2) aMask |= 2;
        if (Abs(yt - myYTop) > 2) aMask |= 4;
        if (Abs(yb - myYBottom) > 2) aMask |= 8;

        switch (aMask)
        {
        case 0:
            aMode = Aspect_TOR_NO_BORDER;
            break;
        case 1:
            aMode = Aspect_TOR_LEFT_BORDER;
            break;
        case 2:
            aMode = Aspect_TOR_RIGHT_BORDER;
            break;
        case 4:
            aMode = Aspect_TOR_TOP_BORDER;
            break;
        case 5:
            aMode = Aspect_TOR_LEFT_AND_TOP_BORDER;
            break;
        case 6:
            aMode = Aspect_TOR_TOP_AND_RIGHT_BORDER;
            break;
        case 8:
            aMode = Aspect_TOR_BOTTOM_BORDER;
            break;
        case 9:
            aMode = Aspect_TOR_BOTTOM_AND_LEFT_BORDER;
            break;
        case 10:
            aMode = Aspect_TOR_RIGHT_AND_BOTTOM_BORDER;
            break;
        default:
            break;
        }  // end switch

        myXLeft = xl;
        myXRight = xr;
        myYTop = yt;
        myYBottom = yb;
    }

    return aMode;
}

// =======================================================================
// function : Ratio
// purpose  :
// =======================================================================
Standard_Real OcctWindow::Ratio() const
{
    QRect aRect = myWidget->rect();
    return Standard_Real(aRect.right() - aRect.left()) / Standard_Real(aRect.bottom() - aRect.top());
}

// =======================================================================
// function : Size
// purpose  :
// =======================================================================
void OcctWindow::Size(Standard_Integer& theWidth, Standard_Integer& theHeight) const
{
    int xl = 0, xr = 0, yt = 0, yb = 0;
    GetSize(xl, xr, yt, yb);

    theWidth = xr - xl;
    theHeight = yb - yt;
}

// =======================================================================
// function : Position
// purpose  :
// =======================================================================
void OcctWindow::Position(Standard_Integer& theX1, Standard_Integer& theY1,
    Standard_Integer& theX2, Standard_Integer& theY2) const
{
    GetSize(theX1, theX1, theY1, theY2);
}
 
void OcctWindow::GetSize(int& xl, int& xr, int& yt, int& yb) const
{
    qreal scale_factor = QGuiApplication::primaryScreen()->devicePixelRatio();

    xl = scale_factor * myWidget->rect().left();
    xr = scale_factor * myWidget->rect().right();
    yt = scale_factor * myWidget->rect().top();
    yb = scale_factor * myWidget->rect().bottom();
}